package com.nbilyk.ntween {
	import com.nbilyk.ntween.events.NTweenEvent;

	public class NBezierTween extends NTween {

		public var bezierProps:Object;

		public function NBezierTween() {
			super();
		}

		override public function setCurrentTime(value:int):void {
			if (value < delay)
				return;
			var t:uint = value - delay;
			if (t >= duration)
				t = duration;
			if (!hasBegun) {
				dispatchEvent(new NTweenEvent(NTweenEvent.TWEEN_START));
				hasBegun = true;
			}
			dispatchEvent(new NTweenEvent(NTweenEvent.TWEEN_UPDATE));

			for (var all:String in initialValues) {
				var newValue:Number;
				if (bezierProps[all] is Array) {
					var t2:Number = ease(t, 0, 1, duration);
					t2 = calculateBezier(initialValues[all], props[all], t2, bezierProps[all]);
					newValue = t2;
				} else {
					newValue = ease(t, initialValues[all], props[all] - initialValues[all], duration);
				}
				target[all] = newValue;
			}

			if (t >= duration) {
				endTween();
			}
		}

		/**
		 * Props to Robert Penner, Zeh Fernando, Nate Chatellier, and Arthur Debert
		 *
		 * @param beginningValue
		 * @param endingValue
		 * @param t Current t for this tweening (0-1), after applying the easing equation
		 * @param p	Array of parameters to use for the bezier tween.
		 */
		private function calculateBezier(beginningValue:Number, endingValue:Number, t:Number, p:Array):Number {
			var pL:uint = p.length;
			if (p.length == 1) {
				return beginningValue + t * (2 * (1 - t) * (p[0] - beginningValue) + t * (endingValue - beginningValue));
			} else {
				var i:uint = Math.floor(t * pL);
				var iT:Number = t * pL - i;
				var p1:Number;
				var p2:Number;
				if (i == 0) {
					p1 = beginningValue;
					p2 = (p[0] + p[1]) / 2;
				} else if (i == pL - 1) {
					p1 = (p[i - 1] + p[i]) / 2;
					p2 = endingValue;
				} else {
					p1 = (p[i - 1] + p[i]) / 2;
					p2 = (p[i] + p[i + 1]) / 2;
				}
				return iT * (2 * (1 - iT) * (p[i] - p1) + iT * (p2 - p1)) + p1;
			}
		}

	}
}